<template>
  <div class="word-forum" :class="theme">
    <div class="dashboard-container">
      <header class="dashboard-header">
        <h1>单词学习系统仪表盘</h1>
        <button @click="toggleTheme" class="theme-toggle">
          {{ theme === 'light' ? '🌙 暗色模式' : '☀️ 亮色模式' }}
        </button>
      </header>

      <div class="stats-grid">
        <!-- 统计卡片 -->
        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(67, 97, 238, 0.1);">
            <span style="color: var(--primary-color);">👥</span>
          </div>
          <div class="stat-info">
            <h3>用户总数</h3>
            <p class="stat-value">{{ formatNumber(stats.totalUsers) }}</p>
            <p class="stat-change">
              较昨日
              <span :style="growthRateStyle">
                <span v-if="stats.growthRateComparedToYesterday >= 0" style="color: #4caf50;">
                  ↑{{ formatNumber(stats.growthRateComparedToYesterday) }}%
                </span>
                <span v-else style="color: #f44336;">
                  ↓{{ formatNumber(stats.growthRateComparedToYesterday) }}%
                </span>
              </span>
            </p>
          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(72, 149, 239, 0.1);">
            <span style="color: #4895ef;">🔥</span>
          </div>
          <div class="stat-info">
            <h3>今日活跃用户</h3>
            <p class="stat-value">{{ formatNumber(stats.activeUsersToday) }}</p>
            <p class="stat-change">
              较昨日
              <span :style="growthRateStyle">
                <span v-if="stats.activeUserGrowthComparedToYesterday >= 0" style="color: #4caf50;">
                  ↑{{ formatNumber(stats.activeUserGrowthComparedToYesterday) }}%
                </span>
                <span v-else style="color: #f44336;">
                  ↓{{ formatNumber(stats.activeUserGrowthComparedToYesterday) }}%
                </span>
              </span>
            </p>
          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(76, 175, 80, 0.1);">
            <span style="color: #4caf50;">📚</span>
          </div>
          <div class="stat-info">
            <h3>今日学习次数</h3>
            <p class="stat-value">{{ formatNumber(stats.studySessionsToday) }}</p>
            <p class="stat-change">
              较昨日
              <span :style="growthRateStyle">
                <span v-if="stats.learningGrowthRateComparedToYesterday >= 0" style="color: #4caf50;">
                  ↑{{ formatNumber(stats.learningGrowthRateComparedToYesterday) }}%
                </span>
                <span v-else style="color: #f44336;">
                  ↓{{ formatNumber(stats.learningGrowthRateComparedToYesterday) }}%
                </span>
              </span>
            </p>

          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(255, 152, 0, 0.1);">
            <span style="color: #ff9800;">⏱️</span>
          </div>
          <div class="stat-info">
            <h3>今日学习时长</h3>
            <p class="stat-value">{{ formatTime(stats.studyTimeToday) }}</p>
            <p class="stat-change">
              较昨日
              <span :style="studyDurationGrowthRateStyle">
                <span v-if="stats.studyDurationGrowthRateComparedToYesterday >= 0" style="color: #4caf50;">
                  ↑{{ formatNumber(stats.studyDurationGrowthRateComparedToYesterday) }}%
                </span>
                <span v-else style="color: #f44336;">
                  ↓{{ formatNumber(stats.studyDurationGrowthRateComparedToYesterday) }}%
                </span>
              </span>
            </p>

          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(156, 39, 176, 0.1);">
            <span style="color: #9c27b0;">❌</span>
          </div>
          <div class="stat-info">
            <h3>错误最多的单词</h3>
            <p class="stat-value">{{ stats.mostMistakenWord || '暂无数据' }}</p>
            <p class="stat-change">错误次数: {{ stats.mistakeCount || 0 }}</p>
          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(244, 67, 54, 0.1);">
            <span style="color: #f44336;">🔄</span>
          </div>
          <div class="stat-info">
            <h3>今日复习完成数</h3>
            <p class="stat-value">{{ formatNumber(stats.reviewsCompletedToday) }}</p>
            <p class="stat-change">
              较昨日
              <span :style="reviewGrowthRateStyle">
                <span v-if="stats.reviewGrowthRateComparedToYesterday >= 0" style="color: #4caf50;">
                  ↑{{ formatNumber(stats.reviewGrowthRateComparedToYesterday) }}%
                </span>
                <span v-else style="color: #f44336;">
                  ↓{{ formatNumber(stats.reviewGrowthRateComparedToYesterday) }}%
                </span>
              </span>
            </p>

          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(33, 150, 243, 0.1);">
            <span style="color: #2196f3;">📖</span>
          </div>
          <div class="stat-info">
            <h3>单词总数</h3>
            <p class="stat-value">{{ formatNumber(stats.totalWords) }}</p>
            <!-- <p class="stat-change">较上周 <span style="color: #4caf50;">↑1.8%</span></p> -->
          </div>
        </div>

        <div class="stat-card">
          <div class="stat-icon" style="background-color: rgba(103, 58, 183, 0.1);">
            <span style="color: #673ab7;">✍️</span>
          </div>
          <div class="stat-info">
            <h3>例句总数</h3>
            <p class="stat-value">{{ formatNumber(stats.totalExamples) }}</p>
            <!-- <p class="stat-change">较上周 <span style="color: #4caf50;">↑3.5%</span></p> -->
          </div>
        </div>
      </div>

      <!-- 图表区域 -->
      <div class="charts-container">
        <div class="chart-card">
          <h3>用户活跃趋势 (最近7天)</h3>
          <div class="chart-wrapper">
            <canvas ref="userActivityChart"></canvas>
          </div>
        </div>

        <!-- <div class="chart-card">
          <h3>学习时长分布 (今日)</h3>
          <div class="chart-wrapper">
            <canvas ref="studyTimeDistributionChart"></canvas>
          </div>
        </div> -->

        <div class="chart-card">
          <h3>单词错误排行榜</h3>
          <div class="chart-wrapper">
            <canvas ref="mistakenWordsChart"></canvas>
          </div>
        </div>

        <!-- <div class="chart-card">
          <h3>学习时段分布</h3>
          <div class="chart-wrapper">
            <canvas ref="studyTimeOfDayChart"></canvas>
          </div>
        </div> -->
      </div>
      <div class="recent-activity">
        <h3>最近活动</h3>
        <div class="activity-list">
          <div v-for="(item, index) in activities" :key="index" class="activity-item">
            <div class="activity-avatar">
              <img :src="item.avatar" :alt="item.user">
            </div>
            <div class="activity-content">
              <p><strong>{{ item.user }}</strong> {{ item.action }}</p>
              <p class="activity-time">{{ item.time }}</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, inject, watch } from 'vue';
import Chart from 'chart.js/auto';
import { getRecentStudyLogsApi } from '../../api/authService.js'
import {
  getUserGrowthDataApi,
  getSigninGrowthDataApi,
  getStudyGrowthDataApi,
  getStudyGrowthTodayVsYesterdayDataApi,
  getErrorWordsStatisticsMostErrorWordsDataApi,
  getStudyTypeGrowthDataApi,
  getWordAndSentenceStatsDataApi,
  getSigninStatsLast_7_DaysDataApi,
  getTopErrorWordsDataApi
} from '../../api/DashboardData.js'
// 主题功能
const theme = inject("theme", ref('light'));
const toggleTheme = () => {
  theme.value = theme.value === 'light' ? 'dark' : 'light';
};

// 图表引用
const userActivityChart = ref(null);
// const studyTimeDistributionChart = ref(null);
const mistakenWordsChart = ref(null);
// const studyTimeOfDayChart = ref(null);

// 模拟数据
const stats = ref({
  totalUsers: 12890,
  growthRateComparedToYesterday: 2.5,
  activeUsersToday: 3421,
  activeUserGrowthComparedToYesterday: 1.8,
  studySessionsToday: 8567,
  learningGrowthRateComparedToYesterday: 3.3,
  studyTimeToday: 12540, // 分钟
  studyDurationGrowthRateComparedToYesterday: 10.1,
  mostMistakenWord: "accommodate",
  mistakeCount: 342,
  reviewsCompletedToday: 5678,
  reviewGrowthRateComparedToYesterday: 5.1,
  totalWords: 12500,
  totalExamples: 35600
});

// 格式化数字
const formatNumber = (num) => {
  return new Intl.NumberFormat().format(num);
};

// 格式化时间
const formatTime = (minutes) => {
  const hours = Math.floor(minutes / 60);
  const mins = minutes % 60;
  return `${hours}h ${mins}m`;
};

// 初始化图表
const initCharts = (signUserDataLabels, signUserDataCount, mistakenWordsData, mistakenWordsCountData) => {
  // console.log(signUserDataLabels, signUserDataCount);
  // 销毁之前的图表实例
  if (userActivityChart.value && userActivityChart.value._chart) {
    userActivityChart.value._chart.destroy();
  }
  // if (studyTimeDistributionChart.value && studyTimeDistributionChart.value._chart) {
  //   studyTimeDistributionChart.value._chart.destroy();
  // }
  if (mistakenWordsChart.value && mistakenWordsChart.value._chart) {
    mistakenWordsChart.value._chart.destroy();
  }
  // if (studyTimeOfDayChart.value && studyTimeOfDayChart.value._chart) {
  //   studyTimeOfDayChart.value._chart.destroy();
  // }

  // 获取当前主题的文本颜色
  const textColor = getComputedStyle(document.documentElement).getPropertyValue('--text-color');
  const borderColor = getComputedStyle(document.documentElement).getPropertyValue('--border-color');

  // 用户活跃趋势图
  new Chart(userActivityChart.value, {
    type: 'line',
    data: {
      labels: signUserDataLabels,
      datasets: [{
        label: '活跃用户数',
        data: signUserDataCount,
        borderColor: '#4361ee',
        backgroundColor: 'rgba(67, 97, 238, 0.1)',
        tension: 0.3,
        fill: true
      }]
    },
    options: {
      responsive: true,
      plugins: {
        legend: {
          labels: {
            color: textColor
          }
        }
      },
      scales: {
        x: {
          grid: {
            color: borderColor
          },
          ticks: {
            color: textColor
          }
        },
        y: {
          grid: {
            color: borderColor
          },
          ticks: {
            color: textColor
          }
        }
      }
    }
  });

  // 学习时长分布图
  // new Chart(studyTimeDistributionChart.value, {
  //   type: 'doughnut',
  //   data: {
  //     labels: ['0-15分钟', '15-30分钟', '30-60分钟', '1-2小时', '2小时以上'],
  //     datasets: [{
  //       data: [15, 25, 30, 20, 10],
  //       backgroundColor: [
  //         '#4361ee',
  //         '#4895ef',
  //         '#4cc9f0',
  //         '#f72585',
  //         '#7209b7'
  //       ],
  //       borderColor: borderColor,
  //       borderWidth: 1
  //     }]
  //   },
  //   options: {
  //     responsive: true,
  //     plugins: {
  //       legend: {
  //         position: 'right',
  //         labels: {
  //           color: textColor
  //         }
  //       }
  //     }
  //   }
  // });

  // 错误单词排行榜
  new Chart(mistakenWordsChart.value, {
    type: 'bar',
    data: {
      labels: mistakenWordsData,
      datasets: [{
        label: '错误次数',
        data: mistakenWordsCountData,
        backgroundColor: 'rgba(244, 67, 54, 0.7)',
        borderColor: '#f44336',
        borderWidth: 1
      }]
    },
    options: {
      responsive: true,
      indexAxis: 'y',
      plugins: {
        legend: {
          display: false
        }
      },
      scales: {
        x: {
          grid: {
            color: borderColor
          },
          ticks: {
            color: textColor
          }
        },
        y: {
          grid: {
            color: borderColor
          },
          ticks: {
            color: textColor
          }
        }
      }
    }
  });

  // 学习时段分布图
  // new Chart(studyTimeOfDayChart.value, {
  //   type: 'radar',
  //   data: {
  //     labels: ['6-9点', '9-12点', '12-14点', '14-17点', '17-20点', '20-24点', '0-6点'],
  //     datasets: [{
  //       label: '学习活跃度',
  //       data: [15, 45, 30, 50, 70, 85, 10],
  //       backgroundColor: 'rgba(72, 149, 239, 0.2)',
  //       borderColor: '#4895ef',
  //       pointBackgroundColor: '#4895ef',
  //       pointBorderColor: '#fff',
  //       pointHoverBackgroundColor: '#fff',
  //       pointHoverBorderColor: '#4895ef'
  //     }]
  //   },
  //   options: {
  //     responsive: true,
  //     plugins: {
  //       legend: {
  //         labels: {
  //           color: textColor
  //         }
  //       }
  //     },
  //     scales: {
  //       r: {
  //         angleLines: {
  //           color: borderColor
  //         },
  //         grid: {
  //           color: borderColor
  //         },
  //         pointLabels: {
  //           color: textColor
  //         },
  //         ticks: {
  //           backdropColor: 'transparent',
  //           color: textColor
  //         }
  //       }
  //     }
  //   }
  // });
};

// 监听主题变化，重新渲染图表
watch(theme, () => {
  setTimeout(initCharts, 100); // 稍等DOM更新
});



const activities = ref([
  {
    user: '张三',
    avatar: 'https://randomuser.me/api/portraits/men/32.jpg',
    action: '学习了50个新单词',
    time: '10分钟前'
  }
])

const getRecentStudyLogs = async () => {
  try {
    const response = await getRecentStudyLogsApi();
    if (response) {
      return response.logs;
      console.log(response);
    } else {
      console.log('获取学习日志失败');
    }
  } catch (error) {
    console.log(error, '获取学习日志失败');
  }
}


const isNewOrReview = (count, sessionType) => {
  const reviewMessages = [
    `用户今日共完成复习任务，累计复习单词 ${count} 个。说明用户正在积极巩固已学词汇，学习节奏稳定，建议后续继续维持当前频率。`,
    `本日复习统计：用户成功复习 ${count} 个词汇，体现出良好的记忆回顾行为。系统已自动记录该复习行为。`,
    `用户已完成今日复习计划，总计 ${count} 个单词。本次复习覆盖范围较广，可结合遗忘曲线适时安排下一轮回顾。`,
    `今日用户在复习环节中处理了 ${count} 个词汇，复习数据已同步更新至学习曲线分析模块。`,
    `复习任务报告：用户今日复习单词数为 ${count}。该数据将用于后续记忆跟踪与复习效率评估。`
  ];

  const newWordMessages = [
    `用户今日新学习单词共计 ${count} 个，学习频率正常。系统已记录该学习行为，将在后续为其生成个性化复习计划。`,
    `学习任务完成：本次新增词汇量为 ${count} 个。学习行为已纳入用户学习轨迹分析模型中。`,
    `今日用户完成了 ${count} 个新词汇的学习任务，学习数据将用于推荐后续学习内容。`,
    `用户今日新增词汇 ${count} 个，记录已保存至数据库，并同步至学习进度统计表。`,
    `用户在本次学习中掌握了 ${count} 个新词汇，该行为已计入学习记录日志，用于综合评估用户词汇量扩展趋势。`
  ];

  const messages = sessionType === 'review' ? reviewMessages : newWordMessages;
  const randomIndex = Math.floor(Math.random() * messages.length);
  return messages[randomIndex];
};

const timeSinceEnd = (endTimeString) => {
  // console.log(endTimeString, 'endTimeStringsssssssssss');
  // 将传入的 UTC 时间转换为 Date 对象
  const endTime = new Date(endTimeString);

  // 获取当前中国时间（UTC+8）
  const now = new Date();
  const chinaNow = new Date(now.toLocaleString("en-US", { timeZone: "Asia/Shanghai" }));

  // console.log(endTime, chinaNow, 'endTime, chinaNow');
  // 计算时间差（毫秒）
  const diff = chinaNow - endTime;

  if (diff < 0) return '刚刚';

  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(diff / (60 * 1000));
  const hours = Math.floor(diff / (60 * 60 * 1000));
  const days = Math.floor(diff / (24 * 60 * 60 * 1000));

  if (seconds < 60) return `${seconds}秒前`;
  if (minutes < 60) return `${minutes}分钟前`;
  if (hours < 24) return `${hours}小时前`;
  return `${days}天前`;
}



const handRecentStudyLogsData = (data) => {
  const AfterData = data.map((item) => ({
    user: item.username,
    avatar: `../../../public/avatar/${item.avatar}.png`,
    action: isNewOrReview(item.word_count, item.session_type),
    time: timeSinceEnd(item.end_time),
  }))
  return AfterData
}


const getUserGrowthData = async () => {
  try {
    const response = await getUserGrowthDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取用户增长数据失败");
    }
  } catch (error) {
    console.log("获取用户增长数据失败", error);
  }
}
const getSigninGrowthData = async () => {
  try {
    const response = await getSigninGrowthDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取用户活跃数据失败");
    }
  } catch (error) {
    console.log("获取用户活跃数据失败", error);
  }
}

const getStudyGrowthData = async () => {
  try {
    const response = await getStudyGrowthDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取用户学习数据失败");
    }
  } catch (error) {
    console.log("获取用户学习数据失败", error);
  }
}

const getStudyGrowthTodayVsYesterdayData = async () => {
  try {
    const response = await getStudyGrowthTodayVsYesterdayDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取用户学习时间数据失败");
    }
  } catch (error) {
    console.log("获取用户学习时间数据失败", error);
  }
}

const getErrorWordsStatisticsMostErrorWordsData = async () => {
  try {
    const response = await getErrorWordsStatisticsMostErrorWordsDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取最多错误单词数据失败");
    }
  } catch (error) {
    console.log("获取最多错误单词数据失败", error);
  }
}


const getStudyTypeGrowthData = async () => {
  try {
    const response = await getStudyTypeGrowthDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取用户学习数据失败");
    }
  } catch (error) {
    console.log("获取用户学习数据失败", error);
  }
}


const getWordAndSentenceStatsData = async () => {
  try {
    const response = await getWordAndSentenceStatsDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取单词总数和例句总数数据失败");
    }
  } catch (error) {
    console.log("获取单词总数和例句总数数据失败", error);
  }
}



const getSigninStatsLast_7_DaysData = async () => {
  try {
    const response = await getSigninStatsLast_7_DaysDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("获取最近7天每天的用户签到数失败");
    }
  } catch (error) {
    console.log("获取最近7天每天的用户签到数失败", error);
  }
}




const getTopErrorWordsData = async () => {
  try {
    const response = await getTopErrorWordsDataApi();
    if (response.data) {
      // console.log(response);
      return response.data;
      console.log(response);
    } else {
      console.log("// 获取错误单词排行榜前五名失败");
    }
  } catch (error) {
    console.log("// 获取错误单词排行榜前五名失败", error);
  }
}
const loadPageData = async () => {
  try {
    const [
      studyLogs,
      userGrowthData,
      signinGrowthData,
      studyGrowthData,
      studyGrowthTodayVsYesterdayData,
      errorWordsStatisticsMostErrorWordsData,
      studyTypeGrowthData,
      wordAndSentenceStatsData,
      signinStatsLast_7_DaysData,
      topErrorWordsData

    ] = await Promise.all([
      getRecentStudyLogs(),
      getUserGrowthData(),
      getSigninGrowthData(),
      getStudyGrowthData(),
      getStudyGrowthTodayVsYesterdayData(),
      getErrorWordsStatisticsMostErrorWordsData(),
      getStudyTypeGrowthData(),
      getWordAndSentenceStatsData(),
      getSigninStatsLast_7_DaysData(),
      getTopErrorWordsData()
    ])
    // console.log(studyLogs, '学习记录');
    activities.value = handRecentStudyLogsData(studyLogs);


    // console.log(userGrowthData, '用户增长数据');
    handStatsData(
      userGrowthData,
      signinGrowthData,
      studyGrowthData,
      studyGrowthTodayVsYesterdayData,
      errorWordsStatisticsMostErrorWordsData,
      studyTypeGrowthData,
      wordAndSentenceStatsData,
      signinStatsLast_7_DaysData,
      topErrorWordsData
    )
    // console.log(handRecentStudyLogsData(studyLogs));
  } catch (error) {
    console.error(error)
    ElMessage.error('请求数据失败')
  }
}

const handStatsData = (
  userGrowthData,
  signinGrowthData,
  studyGrowthData,
  studyGrowthTodayVsYesterdayData,
  errorWordsStatisticsMostErrorWordsData,
  studyTypeGrowthData,
  wordAndSentenceStatsData,
  signinStatsLast_7_DaysData,
  topErrorWordsData
) => {
  stats.value.totalUsers = userGrowthData.todayTotal;
  stats.value.growthRateComparedToYesterday = parseFloat(userGrowthData.growthRate);
  stats.value.activeUsersToday = signinGrowthData.todaySignins;
  stats.value.activeUserGrowthComparedToYesterday = parseFloat(signinGrowthData.growthRate);
  stats.value.studySessionsToday = studyTypeGrowthData.todayNew;
  stats.value.learningGrowthRateComparedToYesterday = parseFloat(studyTypeGrowthData.newGrowthRate);
  stats.value.studyTimeToday = studyGrowthTodayVsYesterdayData.todayStudyLogs
  stats.value.studyDurationGrowthRateComparedToYesterday = parseFloat(studyGrowthTodayVsYesterdayData.growthRate);
  stats.value.mostMistakenWord = errorWordsStatisticsMostErrorWordsData.word
  stats.value.mistakeCount = errorWordsStatisticsMostErrorWordsData.totalErrorCount
  stats.value.reviewsCompletedToday = studyTypeGrowthData.todayReview
  stats.value.reviewGrowthRateComparedToYesterday = parseFloat(studyTypeGrowthData.reviewGrowthRate);
  stats.value.totalWords = wordAndSentenceStatsData.wordCount;
  stats.value.totalExamples = wordAndSentenceStatsData.sentenceCount;
  initCharts(
    signinStatsLast_7_DaysData.map(item => item.date),
    signinStatsLast_7_DaysData.map(item => item.userCount),
    topErrorWordsData.map(item => item.word),
    topErrorWordsData.map(item => item.totalErrorCount)
  );
  // console.log(signinStatsLast_7_DaysData);
  // console.log(stats.value.growthRateComparedToYesterday);
}


// 组件挂载时初始化图表
onMounted(() => {
  loadPageData();
});
</script>

<style scoped>
.word-forum {
  --bg-color: #f8f9fa;
  --text-color: #333;
  --primary-color: #4361ee;
  --secondary-color: #6c757d;
  --border-color: #e1e4e8;
  --card-bg: #fff;
  --hover-bg: #f1f3f5;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  height: 80vh;
  /* background-color: var(--bg-color); */
  color: var(--text-color);
  transition: background-color 0.3s, color 0.3s;
}

.word-forum.dark {
  --bg-color: #1a1a1a;
  --text-color: #e0e0e0;
  --primary-color: #4895ef;
  --secondary-color: #8e8e8e;
  --border-color: #333;
  --card-bg: #2d2d2d;
  --hover-bg: #383838;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.dashboard-container {
  max-width: 100%;
  margin: 0 auto;
  padding: 20px;
}

.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
}

.dashboard-header h1 {
  font-size: 24px;
  font-weight: 600;
  margin: 0;
}

.theme-toggle {
  background-color: var(--primary-color);
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.theme-toggle:hover {
  background-color: var(--primary-color);
  opacity: 0.9;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background-color: var(--card-bg);
  border-radius: 8px;
  padding: 20px;
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  transition: transform 0.3s, box-shadow 0.3s;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.stat-icon {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 15px;
  font-size: 24px;
}

.stat-info h3 {
  font-size: 14px;
  font-weight: 500;
  margin: 0 0 5px 0;
  color: var(--secondary-color);
}

.stat-value {
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 5px 0;
}

.stat-change {
  font-size: 12px;
  margin: 0;
  color: var(--secondary-color);
}

.charts-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(700px, 1fr));
  gap: 20px;
  width: 100%;
  box-sizing: border-box;
}

.chart-card {
  background-color: var(--card-bg);
  border-radius: 8px;
  padding: 20px;
  box-shadow: var(--shadow);
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.chart-card h3 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 16px;
}

.chart-container {
  position: relative;
  width: 100%;
  height: 300px;
}

.chart-wrapper {
  position: relative;
  width: 100%;
  height: 300px;
  /* 👈 你可以自由调高低，比如 250px 或 400px */
}

.chart-wrapper canvas {
  width: auto !important;
  height: 100% !important;
}

@media (max-width: 768px) {
  .stats-grid {
    grid-template-columns: 1fr;
  }

  .charts-container {
    grid-template-columns: 1fr;
  }
}

.recent-activity {
  margin-top: 2vh;
  background-color: var(--card-bg);
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: var(--shadow);
}

.recent-activity h3 {
  margin: 0 0 1rem 0;
  font-size: 1rem;
}

.activity-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.activity-item {
  display: flex;
  gap: 1rem;
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--border-color);
}

.activity-item:last-child {
  border-bottom: none;
}

.activity-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
}

.activity-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.activity-content {
  flex: 1;
}

.activity-content p {
  margin: 0;
  line-height: 1.5;
}

.activity-time {
  font-size: 0.8rem;
  color: var(--text-secondary);
}
</style>